﻿using COMMON.ENCRYPT.sha1;
using COMMON.Http;
using COMMON.Http.Sender;
using System;
using System.Collections.Generic;
using System.Linq;

namespace EBQ_ROP_SDK_NET.rop
{
    class RopClient
    {

        public string appKey { get; set; }

        public string appSecert { get; set; }

        public string endpoint { get; set; }

        public String version { get; set; }

        public RopClient()
        {

        }

        public RopClient(string appKey, string appSecert, string endpiont, string version)
        {
            this.appKey = appKey;
            this.appSecert = appSecert;
            this.endpoint = endpoint;
            this.version = version;
        }

        public RopClient(string appKey, string appSecert, string endpiont)
        {
            this.appKey = appKey;
            this.appSecert = appSecert;
            this.endpoint = endpoint;
            this.version = "1.0";
        }

        public RopClient(string appKey, string appSecert, bool isSandBox)
        {
            this.appKey = appKey;
            this.appSecert = appSecert;
            this.endpoint = isSandBox ? "http://sandbox.api.junziqian.com/services" : "http://api.junziqian.com/services";
            this.version = "1.0";
        }

        public RopClient(string appKey, string appSecert, bool isSandBox, string version)
        {
            this.appKey = appKey;
            this.appSecert = appSecert;
            this.endpoint = isSandBox ? "http://sandbox.api.junziqian.com/services" : "http://api.junziqian.com/services";
            this.version = version;
        }






        public string send(String method, SortedDictionary<string, object> paras)
        {


            #region 头信息
            SortedDictionary<string, Object> header = new SortedDictionary<string, Object>();//http头
            header.Add("method", method);    // 修改调用方法 ，如果是基于哈希的实现调用 preservation.create 方法
            header.Add("locale", "zh_CN");
            header.Add("appKey", appKey);
            header.Add("v", version);
            DateTime start = new DateTime(1970, 1, 1, 0, 0, 0);

            header.Add("ts", (DateTime.Now.AddHours(-8).Ticks - start.Ticks) / 10000L);//C# DateTime ticks 转换成 格里高利时间毫秒值

            header.Add("sign", genSign(serialize(paras, false), header, appSecert).ToUpper());//文件不参与签名
            #endregion 头信息
            PostSender sender_ = new PostSender(endpoint, serialize(paras, true), header); //对象类型的走json

            return ResponseHelper.GetResponseString(sender_.send(5000, null, null));
        }

        private SortedDictionary<string, object> serialize(SortedDictionary<string, object> paras, bool keepFile)
        {
            SortedDictionary<string, object> target = new SortedDictionary<string, object>();

            foreach (string key in paras.Keys)
            {
                String value;
                object v = paras[key];
                if (v is UploadFile)
                {//文件
                    value = v.ToString();
                }
                else if (v.GetType().IsValueType || v is String)//值类型
                {
                    value = v.ToString();
                }
                else
                {//对象类型参数
                    value = Newtonsoft.Json.JavaScriptConvert.SerializeObject(v);
                }

                if (!keepFile && v is UploadFile)
                {
                    //忽略掉文件
                }
                else
                {
                    target.Add(key, value);
                }
            }

            return target;
        }


        /// <summary>
        /// 签名生成方法
        /// </summary>
        /// <param name="paras">请求参数</param>
        /// <param name="header">http头信息</param>
        /// <param name="appSecert">调用app秘钥</param>
        /// <returns></returns>
        private string genSign(IDictionary<string, Object> paras, IDictionary<string, Object> header, string appSecert)
        {
            //linq 如果项目.net版本不支持linq请实现字典的排序即可
            paras = (from entry in paras
                     orderby entry.Key ascending
                     select entry).ToDictionary(pair => pair.Key, pair => pair.Value);
            header = (from entry in header
                      orderby entry.Key ascending
                      select entry).ToDictionary(pair => pair.Key, pair => pair.Value);

            string target = appSecert;

            foreach (string key in paras.Keys)
            {
                target += key + paras[key];
            }

            foreach (string key in header.Keys)
            {
                target += key + header[key];
            }
            //target += "ext" + "cv%011.1.1";

            Console.WriteLine("签名前的参数：" + target);
            return SHA1Encoder.encode(target);
        }
    }
}
